package com.example.java8.feature_04;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class TestOptional {

    public static void main(String[] args){

        // of()方法创建Optional对象如果传入参数为null,则会抛出异常
        Optional<User> optional = Optional.of(new User("帝王神龟"));

        // ofNullable()方法允许传入null对象
        Optional<User> optional1 = Optional.ofNullable(null);

        // 获取对象的值
        User user = optional.get();
        System.out.println(user.getName());

        // 返回默认值，如果ofNullable传入对象为null, 则返回orElse方法传入的对象
        User u = null;
        User user1 = Optional.ofNullable(u).orElse(new User("珠圆玉润"));
        System.out.println(user1.getName());

        // 返回默认值，如果ofNullable传入对象为null, 则返回orElseGet方法传入的供应商返回的值
        User u2 = Optional.ofNullable(u).orElseGet(() -> createUser());
        System.out.println(u2.getName());

        // orElseThrow 如果ofNullable传入对象为null，则抛出异常
        //Optional.ofNullable(u).orElseThrow();
        // 返回自定义异常
        //Optional.ofNullable(u).orElseThrow(() -> new IllegalArgumentException());

        // isPresent 判断值是否为null，value != null
        System.out.println(Optional.ofNullable(u).isPresent());
        // isEmpty 判断值是否为null，value == null
        System.out.println(Optional.ofNullable(u).isEmpty());


        // map方法转换值，如果包装对象不为null,则使用map方法返回对象属性,否则返回18
        Integer age = Optional.ofNullable(u).map(obj -> obj.getAge()).orElse(18);
        System.out.println(age);

        // flatMap方法同样用于值转换,与map方法区别在于flatMap方法接收的是Optional
        String address = Optional.ofNullable(createUser()).flatMap(obj -> obj.getAddress()).orElse("冰岛");
        System.out.println(address);


        // 过滤 filter
        User u3 = Optional.ofNullable(createUser()).filter(obj -> obj.getName().contains("hai")).get();
        System.out.println(u3.getName());


        // or() 方法与 orElse() 和 orElseGet() 类似，它们都在对象为空的时候提供了替代情况。
        // or() 的返回值是由 Supplier 参数产生的另一个 Optional 对象
        User u4 = Optional.ofNullable(u).or(() -> Optional.of(createUser())).get();
        System.out.println(u4.getName());


        // ifPresentOrElse() 方法需要两个参数：一个 Consumer 和一个 Runnable。
        // 如果对象包含值，会执行 Consumer 的动作，否则运行 Runnable
        Optional.ofNullable(u)
                .ifPresentOrElse(obj -> System.out.println("user is null"),
                        () -> System.out.println("user is not null"));


        // stream() 方法，它通过把实例转换为 Stream 对象，从而可以使用Stream API
        List<String> names = Optional.ofNullable(createUser())
                .stream().map(obj -> obj.getName()).collect(Collectors.toList());
        System.out.println(names);
    }


    public static User createUser(){
        return new User("deleerhai");
    }

    public static class User {
        private String name;

        private Integer age;

        private String address;

        public User(String name){
            this.name = name;
        }

        public String getName(){
            return this.name;
        }

        public Integer getAge(){
            return this.age;
        }

        public Optional<String> getAddress(){
            return Optional.ofNullable(this.address);
        }
    }

}
